/**
 * \brief  CPU (processing time) manager session interface
 * \author Christian Helmuth
 * \date   2006-06-27
 *
 * :Question:
 *
 *   Why are thread operations not methods of the thread but
 *   methods of the CPU session?
 *
 * :Answer:
 *
 *   This enables the CPU session to impose policies on thread
 *   operations. These policies are based on the session
 *   construction arguments. If thread operations would be
 *   provided as thread methods, Thread would need to consult
 *   its container object (its CPU session) about the authorization
 *   of each operation and, thereby, would introduce a circular
 *   dependency between CPU session and Thread.
 */

/*
 * Copyright (C) 2006-2009 Christian Helmuth
 * Genode Labs, Feske & Helmuth Systementwicklung GbR
 *
 * This file is part of the Genode OS framework, which is distributed
 * under the terms of the GNU General Public License version 2.
 */

#ifndef _INCLUDE__CPU_SESSION__CPU_SESSION_H_
#define _INCLUDE__CPU_SESSION__CPU_SESSION_H_

#include <base/stdint.h>
#include <base/exception.h>
#include <base/thread_state.h>
#include <thread/capability.h>

namespace Genode {

	class Cpu_session
	{
		protected:

			enum Opcode {
				CREATE_THREAD, KILL_THREAD, FIRST, NEXT, SET_PAGER, START,
				CANCEL_BLOCKING, NAME, STATE
			};

		public:

			/*********************
			 ** Exception types **
			 *********************/

			class Thread_creation_failed : public Exception { };


			static const char *service_name() { return "CPU"; }

			enum { THREAD_NAME_LEN = 32 };

			virtual ~Cpu_session() { }

			/**
			 * Create a new thread
			 *
			 * \param   name  name for the thread
			 * \return        capability representing the new thread
			 * \throw         Thread_creation_failed
			 */
			virtual Thread_capability create_thread(const char *name) = 0;

			/**
			 * Kill an existing thread
			 *
			 * \param thread  capability of the thread to kill
			 */
			virtual void kill_thread(Thread_capability thread) = 0;

			/**
			 * Retrieve thread list of CPU session
			 *
			 * The next() function returns an invalid capability if the
			 * specified thread does not exists or if it is the last one
			 * of the CPU session.
			 */
			virtual Thread_capability first() = 0;
			virtual Thread_capability next(Thread_capability curr) = 0;

			/**
			 * Set paging capabilities for thread
			 *
			 * \param thread  thread to configure
			 * \param pager   capability used to propagate page faults
			 */
			virtual int set_pager(Thread_capability thread,
			                      Thread_capability pager) = 0;

			/**
			 * Modify instruction and stack pointer of thread - start the
			 * thread
			 *
			 * \param thread  thread to start
			 * \param ip      initial instruction pointer
			 * \param sp      initial stack pointer
			 *
			 * \return        0 on success
			 */
			virtual int start(Thread_capability thread, addr_t ip, addr_t sp) = 0;

			/**
			 * Cancel a currently blocking operation
			 *
			 * \param thread  thread to unblock
			 */
			virtual void cancel_blocking(Thread_capability thread) = 0;

			/**
			 * Return thread name
			 *
			 * \param thread    thread to query
			 * \param name_dst  destination string buffer
			 * \param name_len  length of destination string buffer
			 *
			 * \return          0 on success
			 */
			virtual int name(Thread_capability thread,
			                 char *name_dst, size_t name_len) = 0;

			/**
			 * Return thread state
			 *
			 * \param thread     thread to spy on
			 * \param state_dst  result
			 *
			 * \return           0 on success
			 */
			virtual int state(Thread_capability thread,
			                  Thread_state *state_dst) = 0;
	};
}

#endif /* _INCLUDE__CPU_SESSION__CPU_SESSION_H_ */
